package com.yueya.media.mongo.impl;

import com.mongodb.*;
import com.yueya.media.mongo.ICollectionDao;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * mongoDB存取Document
 *
 **/
@Component
public class CollectionDaoImpl implements ICollectionDao {

    private static Logger logger = LoggerFactory.getLogger(CollectionDaoImpl.class);
    @Autowired
    private MongodbFactory mongdbFactory;

    public void setMongdbFactory(MongodbFactory mongdbFactory) {
        this.mongdbFactory = mongdbFactory;
    }

    @Override
    public Map<String, Object> queryByID(String collectionName, String Id) throws Exception {
        DBCollection collection = mongdbFactory.getDbCollection(collectionName);
        BasicDBObject query = new BasicDBObject("_id", new ObjectId(Id));
        DBObject dbObject = collection.findOne(query);
        if (dbObject != null) {
            return dbObject.toMap();
        }
        return null;
    }

    @Override
    public List<Map<String, Object>> queryByDoc(String collectionName, Map<String, Object> doc) {
        DBCollection collection = mongdbFactory.getDbCollection(collectionName);
        BasicDBObject query = new BasicDBObject(doc);
        DBCursor dbCursor = collection.find(query);
        Iterator<DBObject> iterator = dbCursor.iterator();
        List<Map<String, Object>> list = new ArrayList<>();
        while (iterator.hasNext()) {
            list.add(iterator.next().toMap());
        }
        return list;
    }

    @Override
    public long countByDoc(String collectionName, Map<String, Object> doc) {
        DBCollection collection = mongdbFactory.getDbCollection(collectionName);
        BasicDBObject query = new BasicDBObject(doc);
        return collection.count(query);
    }

    /**
     * @param collectionName
     * @param obj            传Map过来
     * @return
     */
    @Override
    public boolean insert(String collectionName, DBObject obj) {
        DBCollection collection = mongdbFactory.getDbCollection(collectionName);
        collection.insert(obj);
        long count = collection.count(obj);
        if (count == 1) {
            logger.info("文档插入成功");
            return true;
        } else {
            logger.info("文档插入失败");
            return false;
        }
    }

    @Override
    public boolean insertBatch(String collectionName, List<DBObject> documents) {
        DBCollection collection = mongdbFactory.getDbCollection(collectionName);
        WriteResult writeResult = collection.insert(documents);
        if (writeResult.getN() == 0) {
            logger.info("批量插入失败！");
            return false;
        }
        return true;
    }

    @Override
    public boolean delete(String collectionName, BasicDBObject doc) {
        DBCollection collection = mongdbFactory.getDbCollection(collectionName);
        WriteResult writeResult = collection.remove(doc);
        if (writeResult.getN() <= 0) {
            logger.info("文档删除失败！请检查文档是否存在");
            return false;
        }
        return true;
    }

    @Override
    public boolean deleteByID(String collectionName, String Id) {
        DBCollection collection = mongdbFactory.getDbCollection(collectionName);
        BasicDBObject query = new BasicDBObject("_id", new ObjectId(Id));
        WriteResult writeResult = collection.remove(query);
        if (writeResult.getN() <= 0) {
            logger.info("文档删除失败！请检查文档是否存在");
            return false;
        }
        return true;
    }

    @Override
    public boolean update(String collectionName, BasicDBObject oldDoc, BasicDBObject newDoc) {
        DBCollection collection = mongdbFactory.getDbCollection(collectionName);
        WriteResult writeResult = collection.update(oldDoc, newDoc);
        if (writeResult.getN() <= 0) {
            logger.info("执行文档更新失败！请检查文档是否存在！");
            return false;
        }
        return true;
    }
}
